import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:ffi';
import 'dart:io';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rider/api/api.dart';
import 'package:flutter_rider/config.dart';
import 'package:flutter_rider/event/location_event.dart';
import 'package:flutter_rider/main.dart';
import 'package:flutter_rider/module/mine/api/user_api.dart';
import 'package:flutter_rider/module/mine/provider/mine_provider.dart';
import 'package:flutter_rider/utils/tip.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:amap_flutter_base/amap_flutter_base.dart';
import '../utils/log.dart';

class LocKit {
  LocKit._privateConstructor();
  static final LocKit _instance = LocKit._privateConstructor();
  static const _LocKey = "_LocKey";
  Map<String, dynamic> _locationResult = {};
  StreamSubscription<Map<String, dynamic>>? _locationListener;
  final AMapFlutterLocation _locationPlugin = AMapFlutterLocation();

  //用来判断定位信息是否重复，重复就不上报了
  String _longitude = "";
  String _latitude = "";

  late Timer _refreshTimer;

  static LocKit get instance {
    return _instance;
  }

  init() async {
    if (Platform.isIOS) {
      requestAccuracyAuthorization();
    }
    var sp = await SharedPreferences.getInstance();
    if (sp.containsKey(_LocKey)) {
      _locationResult = jsonDecode(sp.getString(_LocKey) ?? "");
    }

    ///注册定位结果监听
    _locationListener = _locationPlugin.onLocationChanged().listen(
        (Map<String, Object> result) {
      var errorCode = result["errorCode"];
      if (errorCode == 5) return; //手动取消回来的定位数据不做处理
      _locationPlugin.stopLocation(); //Android 定位结束必须停止，不然下次定位会失败！！！！
      _locationResult = result;
      Log.i("定时器 --- 定位结果loc: " + _locationResult.toString());
      if (result.containsKey('latitude') && result.containsKey('longitude')) {
        // eventBus.fire(LocationEvent()); //刷新我的页面地址
        var lng = _locationResult["longitude"].toString();
        var lat = _locationResult["latitude"].toString();

        if (_latitude == lat && _longitude == lng) {
          ///两次位置相同不上报
          return;
        }
        _latitude = lat;
        _longitude = lng;

        var json = {};
        json["lng"] = _longitude;
        json["lat"] = _latitude;

        Api.post(UserApi.location, json, (data, response) {});
        sp.setString(_LocKey, jsonEncode(_locationResult)); //存一份本地经纬度
      }
    }, onError: (onError) {
      print(onError);
    });
  }

  destroy() {
    _locationListener?.cancel();
    _locationPlugin.destroy();
  }

  ///获取定位信息
  Map<String, dynamic> getData() {
    return _locationResult;
  }

  startLocation() {
    //立马执行一次定位 由于定时器不会立马启动
    _setLocationOption(); //Android 必须在定位之前重新设置不然没法定位！
    _locationPlugin.startLocation();

    _refreshTimer = Timer.periodic(const Duration(seconds: 10), (timer) {
      Log.i("定时器开始定位");
      _setLocationOption(); //Android 必须在定位之前重新设置不然没法定位！
      _locationPlugin.startLocation();
    });
  }

  stopLocation() {
    _locationPlugin.stopLocation();
    if (_refreshTimer.isActive) {
      _refreshTimer.cancel();
    }

    Log.i("定时器停止定位");
  }

  ///获取iOS native的accuracyAuthorization类型
  void requestAccuracyAuthorization() async {
    AMapAccuracyAuthorization currentAccuracyAuthorization =
        await _locationPlugin.getSystemAccuracyAuthorization();
    if (currentAccuracyAuthorization ==
        AMapAccuracyAuthorization.AMapAccuracyAuthorizationFullAccuracy) {
      print("精确定位类型");
    } else if (currentAccuracyAuthorization ==
        AMapAccuracyAuthorization.AMapAccuracyAuthorizationReducedAccuracy) {
      print("模糊定位类型");
    } else {
      print("未知定位类型");
    }
  }

  /// 动态申请定位权限
  void requestPermission() async {
    // 申请权限
    bool hasLocationPermission = await requestLocationPermission();
    if (hasLocationPermission) {
      Log.i("定位权限申请通过");
    } else {
      Log.i("定位权限申请不通过");
    }
  }

  /// 申请定位权限
  /// 授予定位权限返回true， 否则返回false
  Future<bool> requestLocationPermission() async {
    //获取当前的权限
    var status = await Permission.location.status;
    if (status == PermissionStatus.granted) {
      //已经授权
      return true;
    } else {
      //未授权则发起一次申请
      status = await Permission.location.request();
      if (status == PermissionStatus.granted) {
        return true;
      } else {
        return false;
      }
    }
  }

  ///设置定位参数
  void _setLocationOption() {
    // if (null != _locationPlugin) {
    AMapLocationOption locationOption = AMapLocationOption();

    ///是否单次定位
    locationOption.onceLocation = true;

    ///是否需要返回逆地理信息
    locationOption.needAddress = true;

    ///逆地理信息的语言类型
    locationOption.geoLanguage = GeoLanguage.DEFAULT;

    locationOption.desiredLocationAccuracyAuthorizationMode =
        AMapLocationAccuracyAuthorizationMode.FullAndReduceAccuracy;

    locationOption.fullAccuracyPurposeKey = "AMapLocationScene";

    ///设置Android端连续定位的定位间隔 统一用定时器10秒执行一次定位
    locationOption.locationInterval = 2000;

    ///设置Android端的定位模式<br>
    ///可选值：<br>
    ///<li>[AMapLocationMode.Battery_Saving]</li>
    ///<li>[AMapLocationMode.Device_Sensors]</li>
    ///<li>[AMapLocationMode.Hight_Accuracy]</li>
    locationOption.locationMode = AMapLocationMode.Hight_Accuracy;

    ///设置iOS端的定位最小更新距离<br>
    locationOption.distanceFilter = -1;

    ///设置iOS端期望的定位精度
    /// 可选值：<br>
    /// <li>[DesiredAccuracy.Best] 最高精度</li>
    /// <li>[DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度 </li>
    /// <li>[DesiredAccuracy.NearestTenMeters] 10米 </li>
    /// <li>[DesiredAccuracy.Kilometer] 1000米</li>
    /// <li>[DesiredAccuracy.ThreeKilometers] 3000米</li>
    locationOption.desiredAccuracy = DesiredAccuracy.Best;

    ///设置iOS端是否允许系统暂停定位
    locationOption.pausesLocationUpdatesAutomatically = false;

    ///将定位参数设置给定位插件
    _locationPlugin.setLocationOption(locationOption);
    // }
  }

  /// 腾讯地图调用
  /// https://lbs.qq.com/webApi/uriV1/uriGuide/uriMobileRoute
  static Future<bool> openTencentMap(LatLng target,
      {String? address, bool showErr = true}) async {
    String url =
        'qqmap://map/routeplan?type=walk&fromcoord=CurrentLocation&tocoord=${target.latitude},${target.longitude}&referer=FN4BZ-6E33P-LFTDB-VRZ4C-NTP3Z-RVFFK&debug=true&to=${address ?? ''}';
    if (Platform.isIOS) url = Uri.encodeFull(url);
    try {
      if (await canLaunch(url) != null) {
        await launch(url);
      }
    } on Exception catch (e) {
      // if (showErr) Future.error('无法调起腾讯地图');
      Tip.show('请安装腾讯地图');
      return false;
    }
    return true;
  }

  /// 高德地图调用
  /// https://lbs.amap.com/api/amap-mobile/guide/ios/route 官方说明
  static Future<bool> openAmap(LatLng target,
      {String? address, bool showErr = true}) async {
    var url = Platform.isAndroid ? 'amapuri://route/plan/?' : 'iosamap://path?';
    url +=
        "&dname=${address ?? ""}&dlat=${target.latitude}&dlon=${target.longitude}&dev=0&t=2";
    try {
      if (await canLaunch(url) != null) {
        await launch(url);
      }
    } on Exception catch (e) {
      // if (showErr)
      // showToastCommon('无法调起高德地图');
      Tip.show('请安装高德地图');
      return false;
    }
    return true;
  }

  /// 调用高德地图导航
  ///  appName 不支持中文传中文报错
  /// [target]目的地, [appName]当前应用名称, [dev]是否偏移(0:lat和lon是已经加密后的,不需要国测加密;1:需要国测加密)
  /// !注意: iOS端需要在Info.plist配置白名单, 可以参考example工程的配置(LSApplicationQueriesSchemes), 具体文档详见 https://lbs.amap.com/api/amap-mobile/guide/ios/ios-uri-information
  // static navigateDrive(
  //   LatLng target, {
  //   String appName = 'appname',
  //   int dev = 1,
  // }) async {
  //   if (Platform.isAndroid) {
  //     final urlScheme =
  //         'androidamap://navi?sourceApplication=$appName&lat=${target.latitude}&lon=${target.longitude}&dev=$dev&style=2';
  //     if (await canLaunch(urlScheme)) {
  //       launch(urlScheme);
  //     } else {
  //       Future.error('无法调起高德地图');
  //     }
  //   } else if (Platform.isIOS) {
  //     final urlScheme =
  //         'iosamap://navi?sourceApplication=$appName&lat=${target.latitude}&lon=${target.longitude}&dev=$dev&style=2';
  //     // final urlScheme =
  //     //     'iosamap://navi?sourceApplication=applicationName&backScheme=applicationScheme&poiname=fangheng&poiid=BGVIS&lat=36.547901&lon=104.258354&dev=1&style=2';
  //     if (await canLaunch(urlScheme)) {
  //       launch(urlScheme);
  //     } else {
  //       Future.error('无法调起高德地图');
  //     }
  //   }
  // }
}
